﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using QQ2564874169.Core.Utils;
using QQ2564874169.Json;

namespace QQ2564874169.Tencent.Weixin
{
    internal static class Exts
    {
        public static XmlNode[] ToArray(this XmlNode node)
        {
            return node.ChildNodes.Cast<XmlNode>().Where(item => item.NodeType != XmlNodeType.Text).ToArray();
        }

        public static XmlNode GetChildByName(this XmlNode node, string nodeName, bool throwEx = true)
        {
            var result = node.ToArray().FirstOrDefault(i => i.Name.Equals(nodeName, StringComparison.OrdinalIgnoreCase));
            if (result == null && throwEx)
            {
                throw new WXException($"缺少指定的节点：{nodeName}。");
            }
            return result;
        }

        public static int? ToInt(this string str)
        {
            int v;
            if (int.TryParse(str, out v))
            {
                return v;
            }
            return null;
        }

        public static long? ToLong(this string str)
        {
            long v;
            if (long.TryParse(str, out v))
            {
                return v;
            }
            return null;
        }

        public static string ToJson(this object obj)
        {
            return JsonHelper.ToJson(obj);
        }

        public static T JsonTo<T>(this string json)
        {
            return (T)JsonHelper.JsonTo(json, typeof(T));
        }

        public static T? ToEnum<T>(this string nameOrValue, string exMsg = null) where T : struct
        {
            if (typeof(T).IsEnum == false)
            {
                throw new NotSupportedException("必须要是枚举类型。");
            }
            int i;
            if (int.TryParse(nameOrValue, out i))
            {
                return (T) (object) i;
            }
            T e;
            if (Enum.TryParse(nameOrValue, true, out e))
            {
                return e;
            }
            if (exMsg != null)
            {
                throw new FormatException(exMsg);
            }
            return default(T?);
        }

        public static DateTime ToDate(this long time, DateAccuracy accuracy = DateAccuracy.Second)
        {
            return ConvertHelper.ToDate(time, accuracy);
        }

        public static long ToLongTime(this DateTime time, DateAccuracy accuracy = DateAccuracy.Second)
        {
            return ConvertHelper.ToLongTime(time, accuracy);
        }

        public static IDictionary<string, string> ToDictionary(this XmlDocument xml, Func<XmlNode, bool> filter)
        {
            var dict = new SortedDictionary<string, string>(StringComparer.Ordinal);
            foreach (XmlNode node in xml.DocumentElement.ChildNodes)
            {
                if (filter(node))
                    dict.Add(node.Name, node.InnerText);
            }
            return dict;
        }

        public static string Base64ToHex(this string base64string)
        {
            var data = Convert.FromBase64String(base64string);
            return string.Join("", data.Select(i => i.ToString("X2")));
        }
    }
}
